package com.mettle.loyaltycard.model;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class LoyaltyCard {
	private Integer cardNo;


	private Customer customer = new Customer();
	private MembershipType membershipType = MembershipType.NORMAL;
	private Integer loyaltyPoints = 100;
	private Double totalAmount =0.0;
	private List<Transaction> transactions = new LinkedList<Transaction>();

	public LoyaltyCard(int i) {
		this.cardNo = i;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
		customer.setLoyaltyCard(this);
	}

	public List<Transaction> getTransactions() {
		return transactions;
	}

	public MembershipType getMembershipType() {
		return membershipType;
	}

	public void setMembershipType(MembershipType membershipType) {
		this.membershipType = membershipType;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cardNo == null) ? 0 : cardNo.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		LoyaltyCard other = (LoyaltyCard) obj;
		if (cardNo == null) {
			if (other.cardNo != null)
				return false;
		} else if (!cardNo.equals(other.cardNo))
			return false;
		return true;
	}

	public Integer getLoyaltyPoints() {
		return loyaltyPoints;
	}

	public void setLoyaltyPoints(Integer loyaltyPoints) {
		this.loyaltyPoints = loyaltyPoints;
	}

	public void addTransaction(Transaction transaction) {
		transactions.add(transaction);
	}

	public void updateCustomer(String name, String email) {
		if (name != null && !"".equals(name)) {
			customer.setName(name);
		} 
		if (email != null && !"".equals(email)) {
			customer.setEmail(email);
		}
	}

	public void addTransaction(Double amount, Date date, Long transactionId) {
		setTotalAmount(getTotalAmount() + amount);
		final Integer pointsForTransaction = getPointsForTransaction(amount);
		setLoyaltyPoints(getLoyaltyPoints() + pointsForTransaction);
		Transaction transaction = new Transaction();
		transaction.setPointsEarned(pointsForTransaction);
		transaction.setPurchaseAmount(amount);
		transaction.setPurchaseDate(date);
		transaction.setTransactionId(transactionId);
		addTransaction(transaction);
		while (membershipType.getNextLevel() != null &&	totalAmount > membershipType.getNextLevel().getThreshold()) {
			membershipType = membershipType.getNextLevel();
		}
	}
	
	Integer getPointsForTransaction(Double amount) {
		Integer perMultiplier = (int) (amount/membershipType.getStep());
		return perMultiplier * membershipType.getPointsPerStep();
	}

	public void setTotalAmount(Double totalAmount) {
		this.totalAmount = totalAmount;
	}

	public Double getTotalAmount() {
		return totalAmount;
	}
}
